package cloud.banson.emojilizer.repo

import android.content.Context
import android.net.Uri
import android.util.Log
import android.widget.Toast
import cloud.banson.emojilizer.R
import cloud.banson.emojilizer.network.NetworkApi
import cloud.banson.emojilizer.utils.TAG
import id.zelory.compressor.Compressor
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream

class EmojilizerRepo(private val context: Context) {

    /**
     * upload image to get a result
     */
    suspend fun uploadImgForResult(file: Uri, hintUser: (String) -> Unit): String {
        /**
         * The code is trying to load an image from the file system into a temporary file.
         * It then deletes the temporary file when it is done uploading.
         * The code attempts to copy the input stream of a file into a temporary file.
         */
        val inputStream = context.contentResolver.openInputStream(file)
        var tempFile = File.createTempFile("tmp", "tmp")
        tempFile.deleteOnExit()
        copyStreamToFile(inputStream = inputStream!!, tempFile)
        val sendImgFile = Compressor.compress(context, tempFile)
        val part = MultipartBody.Part.createFormData(
            "pic", "myPic", RequestBody.create(
                MediaType.parse("image/*"),
                sendImgFile
            )
        )
        Log.d(TAG, "${part.body().contentLength()}")
        var result: String? = null
        withContext(Dispatchers.IO) {
            try {
                result = NetworkApi.retrofitService.uploadImage(part).body()
            } catch (e: Exception) {
                Log.e(TAG, "uploadImgForResult: ${e.message + "\n" + e.cause}")
                e.printStackTrace()
                hintUser(context.getString(R.string.network_error))
            }
        }
        Log.d(TAG, "uploadImgForResult: ${result}")
        return result ?: ""
    }

    private fun copyStreamToFile(inputStream: InputStream, outputFile: File) {
        inputStream.use { input ->
            val outputStream = FileOutputStream(outputFile)
            outputStream.use { output ->
                val buffer = ByteArray(4 * 1024) // buffer size
                while (true) {
                    val byteCount = input.read(buffer)
                    if (byteCount < 0) break
                    output.write(buffer, 0, byteCount)
                }
                output.flush()
            }
        }
    }
}